namespace Tests
{
    using System;
    using NUnit.Framework;
    using SPDeploy.Library;
    using SPDeploy.Library.Exceptions;
    using SPDeploy.Library.Helpers;
    using SPDeploy.Library.Interfaces;
    using SPDeploy.Library.Processing.Library;

    [TestFixture]
    public class ResolverFixture
    {
        #region Setup/Teardown

        [SetUp]
        public void Init()
        {
            _resolver = new ProcessorRegistry(new DummyLogger(), new DummyWireUp());
        }

        #endregion

        public class DummyLogger : ILogWriter
        {
            #region ILogWriter Members

            public void Write(LogSeverity severity, string sourceName, string format, params object[] args)
            {
            }

            #endregion
        }

        public class DummyWireUp : IProcessorSettingsWireUp
        {
            #region IProcessorSettingsWireUp Members

            public void Wireup(ProcessorSettingsManager manager, ILogWriter logger)
            {
            }

            #endregion
        }

        public class ProcessorTarget
        {
        }

        public class DummyProcessor : IDeploymentTargetProcessor<ProcessorTarget, int>
        {
            #region IDeploymentTargetProcessor<ProcessorTarget,int> Members

            public ILogWriter LogWriter
            {
                set { }
            }

            public bool CanProcess(Type t)
            {
                return typeof (ProcessorTarget) == t;
            }

            public string Name
            {
                get { return "DummyProcessor"; }
            }

            public int Install(ProcessorContext ctx, ProcessorTarget config)
            {
                return 0;
            }

            public int Uninstall(ProcessorContext ctx, ProcessorTarget config)
            {
                return 0;
            }

            public int Update(ProcessorContext ctx, ProcessorTarget oldConfig, ProcessorTarget newConfig)
            {
                return 0;
            }

            #endregion
        }

        private IResolver<IDeploymentTargetProcessor> _resolver;

        [Test]
        public void CannotAddDuplicates()
        {
            var processor = new DummyProcessor();
            _resolver.Register(processor);
            Assert.Throws(typeof (DuplicateValueException), () => _resolver.Register(processor));
        }

        [Test]
        public void RegisterUnregisterUpdatesProcessorCount()
        {
            var processor = new DummyProcessor();
            _resolver.Register(processor);
            Assert.AreEqual(1, _resolver.Count);
            Assert.AreEqual(true, _resolver.Unregister(processor));
            Assert.AreEqual(0, _resolver.Count);
        }

        [Test]
        public void ResolveFailsForUnmatchedType()
        {
            _resolver.Register(new DummyProcessor());
            Assert.AreEqual(null, _resolver.Resolve(typeof (string)));
        }

        [Test]
        public void ResolveFailsWithoutProcessors()
        {
            Assert.AreEqual(null, _resolver.Resolve(typeof (ProcessorTarget)));
        }

        [Test]
        public void ResolveSuccessfulForMatchedType()
        {
            var processor = new DummyProcessor();
            _resolver.Register(processor);
            Assert.AreSame(processor, _resolver.Resolve(typeof (ProcessorTarget)));
        }
    }
}